<?php
/**
 * Created by JetBrains PhpStorm.
 * User: Bezdelnickz
 * Date: 19.03.13
 * Time: 15:04
 * To change this template use File | Settings | File Templates.
 */
$PATH = Config::getInstance()->getBasePath();
require_once("$PATH/util/EncodingConverter.php");

class PatternUtil
{
    private static $_instance;

    private function __construct()
    {
    }

    public static function getInstance()
    {
        if (!self::$_instance)
            self::$_instance = new PatternUtil();
        return self::$_instance;
    }

    public function merge($template, $mapping)
    {
        try {
            foreach ($mapping as $key => $value) {
                $template = str_replace("#" . $key . "#", $value, $template);
            }
        } catch (ErrorException $err) {
            //
        }
        return $template;
    }

    public function getObjectFromArray(AbstractController $controller, $row)
    {
        $instance = $controller->getNewCopyOfObject();

        $setterName = "set" . $controller->getIdMapping()->getFieldName();
        $instance->$setterName($row[$controller->getIdMapping()->getColumnName()]);

        $mapping = $controller->getMappings();
        foreach ($mapping as $mapRow) {
            $setterName = "set" . $mapRow->getFieldName();
            $instance->$setterName(
                //EncodingConverter::getInstance()->utf8_to_cp1251(
                EncodingConverter::getInstance()->utf8_to_cp1251(
                    $row[$mapRow->getColumnName()]
                )
                //)
            );
        }
        return $instance;
    }

    /**
     * Метод для получения строк содержащих перечисление названий столбцов таблицы и
     * перечисление значений, добавляемых в таблицу
     * @param $dataObj - Объект, содержащий данные
     * @param $ormMapping - Маппинг для данной сущности
     * @return array Нулевой элемент - строка с именами полей;
     *  Первый элемент - строка с перечисленными значениями
     */
    public function getColumnsAndValuesWhereValueNotNull($dataObj, $ormMapping)
    {
        $columns = "";
        $values = "";
        foreach ($ormMapping as $ormMap) {
            $getterName = "get" . $ormMap->getFieldName();
            if ($dataObj->$getterName()) {
                $columns = $columns . $ormMap->getColumnName() . ",";

                switch ($ormMap->getType()) {
                    case "string" :
                        $values = $values . "'" . $dataObj->$getterName() . "',";
                        break;
                    case "date" :
                        $values = $values . "'" . $dataObj->$getterName() . "',";
                        break;
                    default:
                        $values = $values . $dataObj->$getterName() . ",";
                }

            }
        }
        $columns = substr($columns, 0, strlen($columns) - 1);
        $values = substr($values, 0, strlen($values) - 1);
        return array($columns, $values);
    }

    public function getColumns(AbstractController $controller, $useIdMapping = true, $useOtherMappings = true)
    {
        $result = "";
        $delimiter = ", ";

        if ($useIdMapping)
            $result = $result . $controller->getIdMapping()->getColumnName() . $delimiter;

        if ($useOtherMappings)
            foreach ($controller->getMappings() as $ormMapping) {
                switch ($ormMapping->getType()) {
                    case "bit" :
                        $result = $result . "cast(" . $ormMapping->getColumnName() .
                            " as unsigned) as " . $ormMapping->getColumnName() . $delimiter;
                        break;
                    default:
                        $result = $result . $ormMapping->getColumnName() . $delimiter;
                }
            }
        $result = substr($result, 0, strlen($result) - strlen($delimiter));
        return $result;
    }

    /**
     * @param $dataObj - Объект, содержащий данные
     * @param $ormMappings - Маппинг объекта для MySql
     * @param $delimiter - элемент, которым отделены присвоения (скорее всего будет равен ", " или " AND " - для запроса UPDATE и для составления условия WHERE соответственно)
     * @return string
     */
    public function getColumnsSetupWithValues($dataObj, $ormMappings, $delimiter)
    {
        $result = "";
        foreach ($ormMappings as $ormMapping) {
            $res = $this->getColumnSetupWithValue($dataObj, $ormMapping);
            if ($res != null) {
                $result = $result . $res . $delimiter;
            }
        }
        $result = substr($result, 0, strlen($result) - strlen($delimiter));
        return $result;
    }

    public function getColumnSetupWithValue($dataObj, OrmMapping $ormMapping)
    {
        //var_dump($dataObj);
        $result = "";
        $getterName = "get" . $ormMapping->getFieldName();

        if ($dataObj->$getterName()) {
            switch ($ormMapping->getType()) {
                case "string" :
                    $result = $result . $ormMapping->getColumnName() . "='" . $dataObj->$getterName() . "'";
                    break;
                case "date" :
                    $result = $result . $ormMapping->getColumnName() . "='" . $dataObj->$getterName() . "'";
                    break;
                default:
                    $result = $result . $ormMapping->getColumnName() . "=" . $dataObj->$getterName();
            }
        }
        return $result;
    }
}
